package com.gitee.wsl.ext.base



inline val Double.Companion.EPS
    get() = 1e-10


inline val Double.Companion.EPS_Range
    get() = EPS..1 - EPS


/**
 * The number of bits used to represent a `double` value.
 *
 * @since 1.5
 */
val Double.Companion.SIZE: Int
    get() = Double.SIZE_BITS

val Double.Companion.BYTES: Int
    get() = Double.SIZE_BYTES

/**
 * The number of bits in the significand of a `double` value.
 * This is the parameter N in section {@jls 4.2.3} of
 * <cite>The Java Language Specification</cite>.
 *
 * @since 19
 */
val Double.Companion.PRECISION: Int
    get() = 53

/**
 * Maximum exponent a finite `double` variable may have.
 * It is equal to the value returned by
 * `Math.getExponent(Double.MAX_VALUE)`.
 *
 * @since 1.6
 */

val Double.Companion.MAX_EXPONENT: Int  // 1023
    get() = (1 shl (SIZE - PRECISION - 1)) - 1

/**
 * Minimum exponent a normalized `double` variable may
 * have.  It is equal to the value returned by
 * `Math.getExponent(Double.MIN_NORMAL)`.
 *
 * @since 1.6
 */
val Double.Companion.MIN_EXPONENT: Int  // -1022
    get() = 1 - MAX_EXPONENT


fun Double.Companion.longBitsToDouble(bits:Long) = fromBits(bits)

fun Double.Companion.doubleToRawLongBits(value:Double) = value.toRawBits()

fun Double.Companion.isInfinite(value:Double) = value.isInfinite()

fun Double.Companion.isNaN(value:Double) = value.isNaN()

fun Double.Companion.isFinite(value:Double) = value.isFinite()


/**
 * This class contains additional constants documenting limits of the
 * `double` type.
 *
 * @author Joseph D. Darcy
 */
object DoubleConsts {
    /**
     * The number of logical bits in the significand of a
     * `double` number, including the implicit bit.
     */
    val SIGNIFICAND_WIDTH: Int = Double.PRECISION

    /**
     * The exponent the smallest positive `double`
     * subnormal value would have if it could be normalized..
     */
    val MIN_SUB_EXPONENT: Int = Double.MIN_EXPONENT - (SIGNIFICAND_WIDTH - 1) // -1074

    /**
     * Bias used in representing a `double` exponent.
     */
    val EXP_BIAS: Int = (1 shl (Double.SIZE - SIGNIFICAND_WIDTH - 1)) - 1 // 1023

    /**
     * Bit mask to isolate the sign bit of a `double`.
     */
    val SIGN_BIT_MASK: Long = 1L shl (Double.SIZE - 1)

    /**
     * Bit mask to isolate the exponent field of a `double`.
     */
    val EXP_BIT_MASK: Long = ((1L shl (Double.SIZE - SIGNIFICAND_WIDTH)) - 1) shl (SIGNIFICAND_WIDTH - 1)

    /**
     * Bit mask to isolate the significand field of a `double`.
     */
    val SIGNIF_BIT_MASK: Long = (1L shl (SIGNIFICAND_WIDTH - 1)) - 1

    /**
     * Bit mask to isolate the magnitude bits (combined exponent and
     * significand fields) of a `double`.
     */
    val MAG_BIT_MASK: Long = EXP_BIT_MASK or SIGNIF_BIT_MASK

    init {
        // verify bit masks cover all bit positions and that the bit
        // masks are non-overlapping
        require(
            ((SIGN_BIT_MASK or EXP_BIT_MASK or SIGNIF_BIT_MASK) == 0L.inv()) &&
                    (((SIGN_BIT_MASK and EXP_BIT_MASK) == 0L) &&
                            ((SIGN_BIT_MASK and SIGNIF_BIT_MASK) == 0L) &&
                            ((EXP_BIT_MASK and SIGNIF_BIT_MASK) == 0L)) &&
                    ((SIGN_BIT_MASK or MAG_BIT_MASK) == 0L.inv())
        )
    }
}